#include "ds18b20.h"

ds18b20_config_t DS18B20_Config[DS18B20_NUM] = {
    {GPIOB, GPIO_Pin_1},
    {GPIOB, GPIO_Pin_7}
};

static GPIO_InitTypeDef GPIO_InitStruct;

void DS18B20_Mode_Input(uint8_t object)
{
    GPIO_InitStruct.GPIO_Pin = DS18B20_Config[object].Pin;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(DS18B20_Config[object].GPIOx, &GPIO_InitStruct);
}

void DS18B20_Mode_Output(uint8_t object)
{
    GPIO_InitStruct.GPIO_Pin = DS18B20_Config[object].Pin;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(DS18B20_Config[object].GPIOx, &GPIO_InitStruct);
}

uint8_t DS18B20_ResetCheck(uint8_t object)
{
    uint8_t time;
    
    //输出模式
    DS18B20_Mode_Output(object);
    
    GPIO_ResetBits(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin);
    delay_us(750);
    GPIO_SetBits(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin);
    delay_us(60);
    
    //输入模式
    DS18B20_Mode_Input(object);
    
    while (GPIO_ReadInputDataBit(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin))
    {
        delay_us(1);
        time++;
        if(time>200)    return 0;
    }
    time = 0;
    while (!GPIO_ReadInputDataBit(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin))
    {
        delay_us(1);
        time++;
        if(time>200)    return 0;
    }
    return 1;
}

// 初始化DS18B20
void DS18B20_Init(void)
{
    for(uint8_t i=0; i<DS18B20_NUM; i++)
    {
        GPIO_InitStruct.GPIO_Pin = DS18B20_Config[i].Pin;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(DS18B20_Config[i].GPIOx, &GPIO_InitStruct);
        
        if(!DS18B20_ResetCheck(i))
        {
            Serial_Printf(USART3, "page2.t3.txt=\"DS18B20 init failed!\"\xff\xff\xff");
            Serial_SendString(USART1, "DS18B20 init failed!");
            return;
        }
    }
    Serial_SendString(USART1, "DS18B20 init complete.");
}

// 发送一个字节的数据
void DS18B20_WriteByte(uint8_t object, uint8_t data)
{
    //切换输出模式
    DS18B20_Mode_Output(object);
    for (uint8_t i = 0; i < 8; i++)
    {
        GPIO_ResetBits(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin);
        delay_us(2);
        if (data & 0x01) {
            GPIO_SetBits(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin);
        }
        delay_us(30);
        GPIO_SetBits(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin);
        delay_us(2);
        data >>= 1;
    }
}

// 读取一个字节的数据
uint8_t DS18B20_ReadByte(uint8_t object)
{
    uint8_t data = 0;
    
    for (uint8_t i = 0; i < 8; i++) {
        //输出模式
        DS18B20_Mode_Output(object);
        GPIO_ResetBits(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin);
        delay_us(2);
        GPIO_SetBits(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin);
        //输入模式
        DS18B20_Mode_Input(object);
        delay_us(8);
        data >>= 1;
        if (GPIO_ReadInputDataBit(DS18B20_Config[object].GPIOx, DS18B20_Config[object].Pin)) {
            data |= 0x80;
        }
        delay_us(60);
    }
    return data;
}

// 读取温度值
float DS18B20_ReadTempe(uint8_t object)
{

    if(!DS18B20_ResetCheck(object)) return 999.99f;
    DS18B20_WriteByte(object, 0xCC);  // 跳过ROM操作
    DS18B20_WriteByte(object, 0x44);  // 启动温度转换
    
    delay_ms(750);  // 等待温度转换完成
    
    if(!DS18B20_ResetCheck(object)) return 999.99f;
    DS18B20_WriteByte(object, 0xCC);  // 跳过ROM操作
    DS18B20_WriteByte(object, 0xBE);  // 读取温度寄存器
    
    uint16_t temp;
    temp = DS18B20_ReadByte(object);
    temp |= (DS18B20_ReadByte(object) << 8);
    
    float temperature = (float)temp * 0.0625;
    return temperature;
}
